package cn.xianshu.mq._05_potics;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 消费者
 *
 *  1.创建链接
 * 	2.创建通道
 * 	3.创建队列
 * 	4.绑定队列到交换机
 * 	5.监听队列
 * 	6.处理消息
 */
public class Consumer1 {
    // 队列名
    public static final String NAME_DECLARE_TOPICS1 = "NAME_DECLARE_TOPICS1";

    public static void main(String[] args) throws IOException, TimeoutException {
        //1.创建链接
        ConnectionFactory factory = new ConnectionFactory(); // 创建工厂
        Connection connection = factory.newConnection(); // 创建链接
        //2.创建通道
        Channel channel = connection.createChannel();
        channel.basicQos(1);

        // 3.创建队列
        channel.queueDeclare(NAME_DECLARE_TOPICS1, // 队列名
                true, // 队列持久化
                false, // 独占队列
                false, // 用完删除队列
                null // 其他配置
                );
        // 4.绑定队列到交换机
        channel.queueBind(NAME_DECLARE_TOPICS1, // 队列名
               Producer.NAME_FANOUT_TOPICS, // 交换机名
                "info"); // 广播方式  不用也不需要写routingKey
        // 4.绑定队列到交换机
        channel.queueBind(NAME_DECLARE_TOPICS1, // 队列名
                Producer.NAME_FANOUT_TOPICS, // 交换机名
                "token.#"); // 广播方式  不用也不需要写routingKey
        // 4.绑定队列到交换机
        channel.queueBind(NAME_DECLARE_TOPICS1, // 队列名
                Producer.NAME_FANOUT_TOPICS, // 交换机名
                "info.*"); // 广播方式  不用也不需要写routingKey

        // 6.拿到消息
        // 消息处理的回调 使用的是匿名内部类可以选择单独写个类来继承DefaultConsumer 重写handleDelivery方法
        Consumer callback = new DefaultConsumer(channel){
            // body就是消息的内容
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("拿到消息了:" + new String(body));
                System.out.println("consumerTag:" + consumerTag);
                System.out.println("交换机:" + envelope.getExchange());
                System.out.println("队列名:" + envelope.getRoutingKey());
                System.out.println("消息的标签(id):" + envelope.getDeliveryTag());
                // System.out.println("额外的参数!" + properties);

                // 执行手动签收
                channel.basicAck(envelope.getDeliveryTag(), // 消息的id
                        false); // 不要签收多个消息，签收当前的消息
            }
        };

        //5.监听队列 从队列中拿到消息之后消息交给回调处理
        channel.basicConsume(NAME_DECLARE_TOPICS1, // 监听的队列名字
                false, // false手动处理  true自动签收  自动签收有个问题  如果中途出现问题，消息消费失败，那么它会自动将信息删除
                callback); // 消息处理回调

        /*try {
            Thread.sleep(50000);
            connection.close();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/
    }
}
